<!DOCTYPE html>
<html lang="en">
<head prefix="og: http://ogp.me/ns#">
  <meta charset="utf-8">
  <title>Hexo 2.7 Released | Hexo</title>
  <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- Canonical links -->
  <link rel="canonical" href="https://hexo.io/news/2014/06/14/hexo-2-7-released/index.html">
  <!-- Alternative links -->
  
  <!-- Icon -->
  <link rel="apple-touch-icon" sizes="57x57" href="/icon/apple-touch-icon-57x57.png">
  <link rel="apple-touch-icon" sizes="114x114" href="/icon/apple-touch-icon-114x114.png">
  <link rel="apple-touch-icon" sizes="72x72" href="/icon/apple-touch-icon-72x72.png">
  <link rel="apple-touch-icon" sizes="144x144" href="/icon/apple-touch-icon-144x144.png">
  <link rel="apple-touch-icon" sizes="60x60" href="/icon/apple-touch-icon-60x60.png">
  <link rel="apple-touch-icon" sizes="120x120" href="/icon/apple-touch-icon-120x120.png">
  <link rel="apple-touch-icon" sizes="76x76" href="/icon/apple-touch-icon-76x76.png">
  <link rel="apple-touch-icon" sizes="152x152" href="/icon/apple-touch-icon-152x152.png">
  <link rel="icon" type="image/png" href="/icon/favicon-196x196.png" sizes="196x196">
  <link rel="icon" type="image/png" href="/icon/favicon-160x160.png" sizes="160x160">
  <link rel="icon" type="image/png" href="/icon/favicon-96x96.png" sizes="96x96">
  <link rel="icon" type="image/png" href="/icon/favicon-16x16.png" sizes="16x16">
  <link rel="icon" type="image/png" href="/icon/favicon-32x32.png" sizes="32x32">
  <meta name="msapplication-TileColor" content="#2f83cd">
  <meta name="msapplication-TileImage" content="/icon/mstile-144x144.png">
  <!-- CSS -->
  <!-- build:css build/css/navy.css -->
  <link rel="stylesheet" href="/css/navy.css">
  <!-- endbuild -->
  <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700" rel="stylesheet" type="text/css">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css">
  <!-- RSS -->
  <link rel="alternate" href="/atom.xml" title="Hexo">
  <!-- Open Graph -->
  <meta name="description" content="Hexo 2.7 has been released with three new features. I’m going to introduce them below. Fragment CachingAlthough Hexo is fast, it may become slow if you have thousands of source files or complicated ca">
<meta property="og:type" content="article">
<meta property="og:title" content="Hexo 2.7 Released">
<meta property="og:url" content="https://hexo.io/news/2014/06/14/hexo-2-7-released/index.html">
<meta property="og:site_name" content="Hexo">
<meta property="og:description" content="Hexo 2.7 has been released with three new features. I’m going to introduce them below. Fragment CachingAlthough Hexo is fast, it may become slow if you have thousands of source files or complicated ca">
<meta property="og:locale" content="en">
<meta property="og:updated_time" content="2017-12-06T21:52:16.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Hexo 2.7 Released">
<meta name="twitter:description" content="Hexo 2.7 has been released with three new features. I’m going to introduce them below. Fragment CachingAlthough Hexo is fast, it may become slow if you have thousands of source files or complicated ca">
<meta name="twitter:site" content="hexojs">
<meta property="fb:admins" content="100000247608790">
  <!-- Google Analytics -->
  
<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-48498357-3', 'auto');
  ga('send', 'pageview');
</script>

</head>

<body>
  <div id="container">
    <header id="header" class="wrapper">
  <div id="header-inner" class="inner">
    <h1 id="logo-wrap">
      <a href="/" id="logo">Hexo</a>
    </h1>
    <nav id="main-nav">
      <a href="/docs/" class="main-nav-link">Docs</a><a href="/api/" class="main-nav-link">API</a><a href="/news/" class="main-nav-link">News</a><a href="/plugins/" class="main-nav-link">Plugins</a><a href="/themes/" class="main-nav-link">Themes</a>
      <a href="https://github.com/hexojs/hexo" class="main-nav-link"><i class="fa fa-github-alt"></i></a>
      <div id="search-input-wrap">
        <div id="search-input-icon">
          <i class="fa fa-search"></i>
        </div>
        <input type="search" id="search-input" placeholder="Search...">
      </div>
    </nav>
    <div id="lang-select-wrap">
      <label id="lang-select-label"><i class="fa fa-globe"></i><span>English</span></label>
      <select id="lang-select" data-canonical="">
        
          <option value="en" selected>English</option>
        
          <option value="zh-tw">正體中文</option>
        
          <option value="zh-cn">简体中文</option>
        
          <option value="ru">Русский</option>
        
          <option value="ko">한국어</option>
        
      </select>
    </div>
    <a id="mobile-nav-toggle">
      <span class="mobile-nav-toggle-bar"></span>
      <span class="mobile-nav-toggle-bar"></span>
      <span class="mobile-nav-toggle-bar"></span>
    </a>
  </div>
</header>

    <div id="content-wrap">
  <div class="wrapper">
    <div class="inner">
      <article class="article post" itemscope itemtype="http://schema.org/Article">
  <header class="article-header">
    
      <h1 class="article-title" itemprop="name">Hexo 2.7 Released</h1>
    
    <a href="/news/2014/06/14/hexo-2-7-released/" class="article-date"><time datetime="2014-06-14T00:00:00.000Z">2014-06-14</time></a>
  </header>
  <div class="article-content" itemprop="articleBody">
    <p>Hexo 2.7 has been released with three new features. I’m going to introduce them below.</p>
<h2 id="Fragment-Caching" class="article-heading"><a href="#Fragment-Caching" class="headerlink" title="Fragment Caching"></a>Fragment Caching<a class="article-anchor" href="#Fragment-Caching" aria-hidden="true"></a></h2><p>Although Hexo is fast, it may become slow if you have thousands of source files or complicated categories or tags. Before the data model upgraded, I borrowed a feature from Ruby on Rails: <strong>Fragment Caching</strong>.</p>
<p>Fragment Caching saves contents within a fragment and serves the cache when the next request come in. A fragment will only be processed once. It can reduce database queries and decrease generation time significantly. For instance, a Hexo site with 300+ source files needs 6 minutes to generate. In Hexo 2.7, it only need 10 seconds!</p>
<p>It can be used in header, footer, sidebar or static contents that won’t be changed during generating. For example:</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">&lt;%- fragment_cache(<span class="string">'header'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="string">'&lt;header&gt;&lt;/header&gt;'</span>;</span><br><span class="line">&#125;); %&gt;</span><br></pre></td></tr></table></figure>
<p>By using <code>fragment_cache</code> helper, contents in the function will be cached.</p>
<p>Partial helper also supports Fragment Caching, you only need to add a <code>{cache: true}</code> option when using partial.</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">&lt;%- partial(<span class="string">'header'</span>, &#123;&#125;, &#123;<span class="attr">cache</span>: <span class="literal">true</span>&#125;) %&gt;</span><br></pre></td></tr></table></figure>
<p><a href="https://github.com/hexojs/hexo-theme-landscape" target="_blank" rel="noopener">Landscape</a> is updated and supports Fragment Caching now. You can check <a href="https://github.com/hexojs/hexo-theme-landscape/commit/d2aedda61571d6994eb72d784ceda2f59d2a8631" target="_blank" rel="noopener">this commit</a> to see what’s changed.</p>
<h2 id="Relative-Link" class="article-heading"><a href="#Relative-Link" class="headerlink" title="Relative Link"></a>Relative Link<a class="article-anchor" href="#Relative-Link" aria-hidden="true"></a></h2><p>Relative Link is supported since Hexo 2.7. But your theme needs some modifications to support it. However, it’s not as hard as you think. You just need to replace the following contents in templates</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">&lt;%- config.root %&gt;&lt;%- path %&gt;</span><br></pre></td></tr></table></figure>
<p>with <code>url_for</code> helper.</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">&lt;%- url_for(path) %&gt;</span><br></pre></td></tr></table></figure>
<p><code>url_for</code> helper will add <code>config.root</code> automatically for you. If you enable <code>relative_link</code> setting, it’ll add a relative path.</p>
<p><a href="https://github.com/hexojs/hexo-theme-landscape" target="_blank" rel="noopener">Landscape</a> is updated for Relative Link. You can check <a href="https://github.com/hexojs/hexo-theme-landscape/commit/d29cbb83356373af27e7b98643f29a27804364af" target="_blank" rel="noopener">this commit</a> to see what’s changed.</p>
<h2 id="Server-Middleware" class="article-heading"><a href="#Server-Middleware" class="headerlink" title="Server Middleware"></a>Server Middleware<a class="article-anchor" href="#Server-Middleware" aria-hidden="true"></a></h2><p>Server Middleware would be familiar if you have ever used <a href="http://www.senchalabs.org/connect/" target="_blank" rel="noopener">Connect</a> or <a href="http://expressjs.com/" target="_blank" rel="noopener">Express</a> before. <a href="http://www.senchalabs.org/connect/" target="_blank" rel="noopener">Connect</a> passes a request through functions called <strong>middleware</strong>. You can make response to the coming in request in middleware.</p>
<p>In Hexo, middleware is served as a type of filter. You can add middleware by registering a new filter. For example:</p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line">hexo.extend.filter.register(<span class="string">'server_middleware'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">app</span>)</span>&#123;</span><br><span class="line">  app.use(<span class="function"><span class="keyword">function</span>(<span class="params">req, res, next</span>)</span>&#123;</span><br><span class="line">    res.setHeader(<span class="string">'X-Powered-By'</span>, <span class="string">'Hexo'</span>);</span><br><span class="line">    next();</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<p>This middleware add a header <code>X-Powered-By</code> and passes the request to the next middleware.</p>

  </div>
  
<section id="comments">
  <div id="disqus_thread"></div>
</section>
<script>
  var disqus_shortname = 'hexojs';
  var disqus_url = 'https://hexo.io/news/2014/06/14/hexo-2-7-released/index.html';
  var disqus_title = "Hexo 2.7 Released";
  var disqus_config = function(){
    this.language = 'en';
  };
  (function(){
    var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
    dsq.src = 'https://go.disqus.com/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
  })();
</script>

</article>

    </div>
  </div>
</div>
    <footer id="footer" class="wrapper">
  <div class="inner">
    <div id="footer-copyright">
      &copy; 2017 <a href="https://github.com/hexojs/hexo/graphs/contributors" target="_blank">Hexo</a><br>
      Documentation licensed under <a href="http://creativecommons.org/licenses/by/4.0/" target="_blank">CC BY 4.0</a>.
    </div>
    <div id="footer-links">
      <a href="https://twitter.com/hexojs" class="footer-link" target="_blank"><i class="fa fa-twitter"></i></a>
      <a href="https://github.com/hexojs/hexo" class="footer-link" target="_blank"><i class="fa fa-github-alt"></i></a>
    </div>
  </div>
</footer>

  </div>
  <div id="mobile-nav-dimmer"></div>
  <nav id="mobile-nav">
  <div id="mobile-nav-inner">
    <ul id="mobile-nav-list">
      <a href="/docs/" class="mobile-nav-link">Docs</a><a href="/api/" class="mobile-nav-link">API</a><a href="/news/" class="mobile-nav-link">News</a><a href="/plugins/" class="mobile-nav-link">Plugins</a><a href="/themes/" class="mobile-nav-link">Themes</a>
      <li class="mobile-nav-item">
        <a href="https://github.com/hexojs/hexo" class="mobile-nav-link" rel="external" target="_blank">GitHub</a>
      </li>
    </ul>
    
  </div>
  <div id="mobile-lang-select-wrap">
    <span id="mobile-lang-select-label"><i class="fa fa-globe"></i><span>English</span></span>
    <select id="mobile-lang-select" data-canonical="">
      
        <option value="en" selected>English</option>
      
        <option value="zh-tw">正體中文</option>
      
        <option value="zh-cn">简体中文</option>
      
        <option value="ru">Русский</option>
      
        <option value="ko">한국어</option>
      
    </select>
  </div>
</nav>
  <!-- Scripts -->
<!-- build:js build/js/main.js -->
<script src="/js/lang_select.js"></script>
<script src="/js/toc.js"></script>
<script src="/js/mobile_nav.js"></script>
<!-- endbuild -->

<!-- Algolia -->

<script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script>
<script type="text/javascript">
document.getElementById('search-input-wrap').classList.add('on');
docsearch({
  apiKey: 'c3d5d4c995b5e0c2ffb5623900279a66',
  indexName: 'hexo',
  inputSelector: '#search-input'
});
</script>


</body>
</html>